#include "AMP_Driver.h"
#include "hx6203sys.h"
#include "DataProcess.h"
#include "delay.h"
#include "stdlib.h"
#include "ui.h"

//ui状态反馈
extern uint8_t NodeState[11];

/*********功放单元（刀片）驱动函数********/
uint16_t PA485_UART_Count=0;	//串口计数
uint8_t PA485_UART_Finish=0;
uint8_t PA485_UART_BUF[128];
uint8_t AmpSendBuf[30];

#define AMP485_SendFrame 0x34
#define AMP_Max_AimRower 680	//刀片目标功率上限720
#define AMP_BiasAddr	101

#define AMP_Max_GateVoltage -4.0f
#define AMPDebugPrint 0

//获取所有刀片状态
void Get9AmpSTA(void){
	uint8_t amp;
	for(amp=0;amp<AMP_NUM;amp++){
		if(GetAmpSTA(amp)){	
			//如果通信异常，累积错误指示
			if(HX6203.AMP[amp].CommErr < 0xff)
                HX6203.AMP[amp].CommErr++;
			if(AMPDebugPrint)
                printf("AMP[%d] CommErr=%d\n",amp,HX6203.AMP[amp].CommErr);
            NodeState[amp] = ABNORMAL;
		}
		else    //通讯正常
        {
            HX6203.AMP[amp].CommErr = 0;
            NodeState[amp] = NORMAL;
        }
	}
}

//获取某刀片状态
uint16_t GetAmpSTA(uint8_t AmpNum){
	uint8_t i,pa,delay;
	//清空串口标志
	i=USART3->SR;
	i=USART3->DR;
	PA485_UART_Count=0;
	PA485_UART_Finish=0;
	//填充查询指令
	AmpSendBuf[0]=AMP485_SendFrame;
	AmpSendBuf[1]=AMP_BiasAddr+AmpNum;	//AMP0=地址100 AMP8=地址108
	AmpSendBuf[2]=0x00;
	AmpSendBuf[3]=0x33;
	AmpSendBuf[4]=dataCount(AmpSendBuf,4);
	//发送指令
	for(i=0;i<5;i++){
		USART3->DR=AmpSendBuf[i];
		while((USART3->SR&0X40)==0);
	}
	//状态清零
	for(pa=0;pa<3;pa++){
		HX6203.AMP[AmpNum].PA[pa].Curr=0;
		HX6203.AMP[AmpNum].PA[pa].Temp=0;
		HX6203.AMP[AmpNum].PA[pa].Vbias=0;
	}
	HX6203.AMP[AmpNum].Vneg=0;
	HX6203.AMP[AmpNum].AimRF=0;
	HX6203.AMP[AmpNum].FwdRF=0;
	HX6203.AMP[AmpNum].RevRF=0;
	
	//等待回复传输完成 通常2ms内会回复，但回复持续时间长达6ms
	delay=12;	//最多等待12ms
	while(delay--){
		delay_ms(1);
		if(PA485_UART_Finish)break;
	}
	if(delay==0)	return 1;	//超时返回
	if(PA485_UART_Finish==0)	return 1;	//超时返回
	if(PA485_UART_BUF[0]!=AMP485_SendFrame)	return 2;	//帧头错误
	if(dataCheck(PA485_UART_BUF,PA485_UART_Count-1))return 3;	//校验错误
	//地址错误

	PA485_UART_Count=0;
	PA485_UART_Finish=0;
	/*********解析数据*********/
	//负电源轨电压
	for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=PA485_UART_BUF[12+i];	
	HX6203.AMP[AmpNum].Vneg=FloatTo4Byte.floatData;
	//目标功率值
	for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=PA485_UART_BUF[16+i];	
	HX6203.AMP[AmpNum].AimRF=FloatTo4Byte.floatData;
	//正向功率值
	for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=PA485_UART_BUF[20+i];	
	HX6203.AMP[AmpNum].FwdRF=FloatTo4Byte.floatData;
	//反向功率值
	for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=PA485_UART_BUF[24+i];	
	HX6203.AMP[AmpNum].RevRF=FloatTo4Byte.floatData;
	
//	if(AMPDebugPrint)printf("AMP[%d] Vneg=%f AimP=%f Fwd=%f Rev=%f\n",AmpNum,HX6203.AMP[AmpNum].Vneg,HX6203.AMP[AmpNum].AimRF,
//	HX6203.AMP[AmpNum].FwdRF,HX6203.AMP[AmpNum].RevRF);
	
	//PA0-2电流-温度-DAC
	for(pa=0;pa<PA_NUM;pa++){
		for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=PA485_UART_BUF[28+pa*4+i];	
		HX6203.AMP[AmpNum].PA[pa].Curr=FloatTo4Byte.floatData;
		
		for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=PA485_UART_BUF[40+pa*4+i];	
		HX6203.AMP[AmpNum].PA[pa].Temp=FloatTo4Byte.floatData;
		
		for(i=0;i<4;i++)FloatTo4Byte.ByteData[i]=PA485_UART_BUF[52+pa*4+i];	
		HX6203.AMP[AmpNum].PA[pa].Vbias=FloatTo4Byte.floatData;
		
//		if(AMPDebugPrint)printf("PA[%d] I=%f T=%f Vb=%f\n",pa,HX6203.AMP[AmpNum].PA[pa].Curr,HX6203.AMP[AmpNum].PA[pa].Temp,
//		HX6203.AMP[AmpNum].PA[pa].Vbias);
	}
	//if(AMPDebugPrint)printf("\n");
	
	return 0;
}

//设置某刀片功率
void SetAmpAimRF(uint8_t AmpNum,uint16_t AimRF){
	uint8_t i;
	//限制刀片目标功率
	if(AimRF>AMP_Max_AimRower)AimRF=AMP_Max_AimRower;	
	//清空串口标志
	i=USART3->SR;
	i=USART3->DR;
	PA485_UART_Count=0;
	PA485_UART_Finish=0;
	//填充缓冲区
	FloatTo4Byte.floatData=AimRF;
	AmpSendBuf[0]=AMP485_SendFrame;
	AmpSendBuf[1]=AMP_BiasAddr+AmpNum;	//AMP0=地址100 AMP8=地址108
	AmpSendBuf[2]=0x01;
	AmpSendBuf[3]=FloatTo4Byte.ByteData[0];
	AmpSendBuf[4]=FloatTo4Byte.ByteData[1];
	AmpSendBuf[5]=FloatTo4Byte.ByteData[2];
	AmpSendBuf[6]=FloatTo4Byte.ByteData[3];
	AmpSendBuf[7]=dataCount(AmpSendBuf,7);
	//发送指令
	for(i=0;i<8;i++){
		USART3->DR=AmpSendBuf[i];
		while((USART3->SR&0X40)==0);
	}
	delay_ms(5);
}
//设置刀片栅压
void SetAmp_GateVoltage(uint8_t AmpNum, float GateVoltage)
{
    if(GateVoltage > AMP_Max_GateVoltage) GateVoltage = AMP_Max_GateVoltage;
    
    //清空串口标志
	USART3->SR;
	USART3->DR;
	PA485_UART_Count=0;
	PA485_UART_Finish=0;
    
    //填充缓冲区
	FloatTo4Byte.floatData = GateVoltage;
	AmpSendBuf[0]=AMP485_SendFrame;
	AmpSendBuf[1]=AMP_BiasAddr+AmpNum;	//AMP0=地址100 AMP8=地址108
	AmpSendBuf[2]=0x03;
    AmpSendBuf[3]=0xff;
    for(uint8_t i=0; i<3; i++)
    {
        AmpSendBuf[4+(i*4)]=FloatTo4Byte.ByteData[0];
        AmpSendBuf[5+(i*4)]=FloatTo4Byte.ByteData[1];
        AmpSendBuf[6+(i*4)]=FloatTo4Byte.ByteData[2];
        AmpSendBuf[7+(i*4)]=FloatTo4Byte.ByteData[3];
    }
	AmpSendBuf[16]=dataCount(AmpSendBuf,16);
    //发送指令
	for(uint8_t i=0; i<17; i++){
		USART3->DR=AmpSendBuf[i];
		while((USART3->SR&0X40)==0);
	}
	delay_ms(5);
}

//向九个刀片写入目标功率，并校验
uint16_t Set9AmpAImRF(uint16_t SetAimRF){
	uint8_t amp;
	uint16_t sta=0;
	for(amp=0;amp<AMP_NUM;amp++){
		SetAmpAimRF(amp,SetAimRF);
		delay_ms(15);	//延迟
		GetAmpSTA(amp);
		if(abs((int)(HX6203.AMP[amp].AimRF - SetAimRF)) > 5){      //求绝对值
			//回读刀片目标功率，如果差距过大，认为设置失败
			sta |= (uint16_t)(1<<amp);
		}
	}
	return sta;
}

//设置9路刀片栅压
uint16_t Set9Amp_GateVoltage(float GateVoltage)
{
    uint16_t sta = 0;
    
    if(GateVoltage > AMP_Max_GateVoltage) GateVoltage = AMP_Max_GateVoltage;
    
    for(uint8_t amp = 0; amp<AMP_NUM; amp++)
    {
        SetAmp_GateVoltage(amp, GateVoltage);
        delay_ms(15);	//延迟
        GetAmpSTA(amp);
        delay_ms(15);	//延迟
        if(abs((int)((HX6203.AMP[amp].Vneg - GateVoltage)*100)) > 5)  //求设定与反馈的绝对值，大于1则判断失败
        {
            BIT_SET(sta, amp);
        }
    }
    return sta;
}

//刀片通信UART（RS485）初始化
//绑定至UART3 PB10 PB11
void PA485_UART_Init(uint32_t bound){
   //GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
 
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_USART3); 
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_USART3); 
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOB,&GPIO_InitStructure); 

	USART_InitStructure.USART_BaudRate = bound;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
	USART_Init(USART3, &USART_InitStructure); //初始化串口3
	
	USART_ITConfig(USART3,USART_IT_RXNE, ENABLE);//开启接收中断
	USART_ITConfig(USART3,USART_IT_IDLE, ENABLE);//开启空闲中断
	
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;//串口3中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
	USART_Cmd(USART3, ENABLE);  //使能串口3
}

//刀片通信UART（RS485）中断入口
//USART3中断处理函数
void USART3_IRQHandler(void)
{
	uint8_t Res;
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //接收到一个字节
	{
		Res =USART_ReceiveData(USART3);//读取1Byte
		if(PA485_UART_Finish==0)//接收未完成
		{
			PA485_UART_BUF[PA485_UART_Count]=Res ;
			PA485_UART_Count++;
		}   		 
  }
	else if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)	//接收完成一帧
	{
		Res=USART3->SR;
		Res=USART3->DR;
		PA485_UART_Finish=1;	//接收完成了
	}
}
